/*
@STI LICENSE
(C) 2006-2008 Universit�t Innsbruck.

This file is part of myOntology.

myOntologyis free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

myOntologyis distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with myOntology.  If not, see <http://www.gnu.org/licenses/>.

@STI LICENSE */
/**
 * 
 */
package org.myontology.view.items;

import java.lang.reflect.Constructor;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.log4j.Logger;
import org.myontology.model.Property;
import org.myontology.model.Relation;
import org.myontology.model.Type;



/**
 *  @author <a href="michael.hackl@sti2.at">Michael Hackl</a>
 * Project: Myontology - www.myontology.org
 * STI
 */
public class ComponentDictionary {

	Logger logger = Logger.getLogger(getClass()); 
	
	private Map<String, Class<? extends ComponentBuilder>> propertyDictionary = new ConcurrentHashMap<String,Class<? extends ComponentBuilder>>();
	private Map<TypeRel,Class<? extends ComponentBuilder>> conventionDictionary = new ConcurrentHashMap<TypeRel, Class<? extends ComponentBuilder>>();


	public void registerConvention(Relation rel, Type type,Class<? extends ComponentBuilder> clazz) {
		conventionDictionary.put(new TypeRel(rel,type), clazz);
	}
	
	public void registerProperty(String key,Class<? extends ComponentBuilder> clazz) {
		propertyDictionary.put(key, clazz);
	}
	
	public ComponentBuilder retrieveComponent(Property prop,FormBuilder builder) {
		Class<? extends ComponentBuilder> clazz = propertyDictionary.get(prop.getKey());
		if (clazz==null) {
			clazz = conventionDictionary.get(new TypeRel(prop.getRelation(),prop.getType()));
		}
		if (clazz==null) {
			logger.error("no componentBuilder registered for: "+new TypeRel(prop.getRelation(),prop.getType()));
			throw new RuntimeException("retrieveComponent error");
		}
		try {
			Constructor<? extends ComponentBuilder> con= clazz.getConstructor(Property.class,FormBuilder.class);
			return con.newInstance(prop,builder);
		} catch (Exception e) {
			logger.error("error initializing ComponentBuilder: "+clazz.getName());
			throw new RuntimeException(e);
		}
	}
	

	
	static class TypeRel {
		public TypeRel(Relation rel, Type type) {
			relation=rel;
			this.type=type;
		}
		private Relation relation;
		private Type type;
		
		@Override
		public boolean equals(Object obj) {
			if (obj instanceof TypeRel) {
				TypeRel tr = (TypeRel) obj;
				return relation.equals(tr.relation) && type.equals(tr.type);
			}
			else
				return super.equals(obj);
		}
		
		@Override
		public String toString() {
			return relation.toString()+type.toString();
		}
		
		@Override
		public int hashCode() {
			return toString().hashCode();
		}
		
	}
	
}
